/*
 * comandos.c
 *
 *  Created on: 20/10/2011
 *      Author: utn_so
 */

#include "consola.h"

#define info 89
#define clean 90
#define trace 91
#define salir 92


void interfazConsola()
{
	printf("####################################\n");
	printf("###### Funciones de la Consola #####\n");
	printf("####################################\n");
	printf("                                    \n");
	printf("1 - info                            \n");
	printf("2 - clean <sector i><sector f>      \n");
	printf("3 - trace lista sectores            \n");
	printf("                                    \n");
	printf("####################################\n");
}

int32_t obtenerNumeroDeOperacion(char *data)
{
	char tokenInfo[] = "info";
	char tokenClean[] = "clean";
	char tokenTrace[] = "trace";
	char tokenSalir[] = "salir";
	if (strcmp(data,tokenInfo) == 0)
		return info;
	if (strcmp(data,tokenClean) == 0)
		return clean;
	if (strcmp(data,tokenTrace) == 0)
		return trace;
	if (strcmp(data,tokenSalir) == 0)
		return salir;
	return 0;
}

void procesarConsola (char *data, int32_t sockPPD)
{
	int32_t parseo;
	char tokenInfo[] = "info";
	char tokenClean[] = "clean";
	char tokenTrace[] = "trace";
	char *cadenaABuscar;
	char *aux= (char *)calloc(sizeof(char),strlen(data));
	if (strcmp(data,"\n") == 0)
		return;
	parseo = parsearData(data,"\n",tokenInfo,&cadenaABuscar);
	memcpy(aux,data,strlen(data));
	if (strchr(aux,' ') != NULL)
	{
		parseo = parsearData(aux," ",tokenClean,&cadenaABuscar);
		parseo = obtenerNumeroDeOperacion(aux);
	}
	parseo = obtenerNumeroDeOperacion(aux);

	switch (parseo)
	{
	case info:
		procesarINFO(sockPPD);
		break;
	case clean:
		parseo = parsearData(data," ",tokenClean,&cadenaABuscar);
		procesarCLEAN(sockPPD,cadenaABuscar);
		break;
	case trace:
		parseo = parsearData(data," ",tokenTrace,&cadenaABuscar);
		procesarTRACE(sockPPD, cadenaABuscar);
		break;
	case salir:
		procesarSALIR(sockPPD);
		break;
	default:
		printf("Ingresó un comando erróneo.\n");
		break;
	}
	free(aux);
}

int32_t stringAInt32 (char *pToken)
{
	int32_t memoriaLiberada=0;
	int32_t token = atoi(pToken);
	memoriaLiberada = liberarMemoria(&pToken);
	return token;
}

void procesarINFO(int32_t sockPPD)
{
	t_NIPC comando;
	int32_t comandoEnviado;
	int32_t cantidad;
	int32_t *chs;

	NIPC_crearpaquete(NULL, CABEZAL, 0, NULL, 0, &comando);

	comandoEnviado = NIPC_enviar (sockPPD, comando);

	comandoEnviado = NIPC_recibir(sockPPD, &comando);

	parsearSectores(comando.payload, &cantidad, &chs);

	printf("C:%d H:%d S:%d\n", chs[0],chs[1],chs[2]);

	NIPC_destruirpaquete(&comando);

}

void procesarCLEAN(int32_t sockPPD,char *cadenaABuscar)
{
	t_NIPC paquete;
	int32_t valorRetorno;
	int32_t sizePaquete = 2 * sizeof(int32_t) + 1;

	NIPC_crearpaquete(NULL, CLEAN,sizePaquete, cadenaABuscar,0, &paquete);
	valorRetorno = NIPC_enviar(sockPPD, paquete);
	valorRetorno = NIPC_recibir(sockPPD, &paquete);

	if (valorRetorno == Retorno_OK)
		printf ("Se setearon a cero todos los sectores de:%s \n",cadenaABuscar);

	NIPC_destruirpaquete(&paquete);
}

void parsearSectores(char *cadenaAseparar, int32_t *cantidad, int32_t **sectores)
{
	char *spTokenSafe;
	char *palabra;
	int32_t contador=0;
	*sectores = (int32_t *) calloc (5, sizeof(int32_t));

	palabra = (strtok_r(cadenaAseparar, " ", &spTokenSafe));
	while (palabra != NULL && contador <= 5)
	{
		*(*sectores + contador) = atoi (palabra);
		palabra = (strtok_r(NULL, " ", &spTokenSafe));
		contador++;
	}
	if (contador > 5)
		*cantidad = -1;
	else
	{
		*sectores = (int32_t *) realloc (*sectores, contador * sizeof(int32_t));
		*cantidad = contador;
	}
}

void procesarTRACE(int32_t sockPPD,char *cadenaABuscar)
{
	t_NIPC paquete;
	int32_t valorRetorno, cantidad, i=0;
	int32_t *sectores;
	int32_t sizePaquete = 5 * sizeof(int32_t) + 4;
	char *posicion;
	char *sector;
	char *sectoresRecorridos;
	char *tiempo;
	float tiempoConsumido;
	char *proximoSector;

	if (cadenaABuscar == NULL)
		printf("El comando TRACE recibe al menos un sector. Inténtelo nuevamente.\n");
	else
	{
		NIPC_crearpaquete(NULL, TRACE, sizePaquete, cadenaABuscar,0, &paquete);
		valorRetorno = NIPC_enviar(sockPPD, paquete);

		parsearSectores(cadenaABuscar, &cantidad, &sectores);
		while (i<cantidad)
		{
			valorRetorno = NIPC_recibir(sockPPD, &paquete);
			posicion = strtok(paquete.payload, "\n");
			sector = strtok (NULL, "\n");
			sectoresRecorridos = strtok (NULL, "\n");
			tiempo = strtok (NULL, "\n");
			proximoSector = strtok (NULL, "\n");

			tiempoConsumido = atof (tiempo);
			printf("\nPosicion Actual: %s\nSector Solicitado: %s\nSectores Recorridos: %s\nTiempo Consumido: %f ms\nProximo Sector: %s\n\n",
					posicion, sector, sectoresRecorridos, tiempoConsumido, proximoSector);
			i++;
		}

//		free(posicion);
////		free(sector);
////		free(sectoresRecorridos);
////		free(tiempo);
////		free(proximoSector);

		NIPC_destruirpaquete(&paquete);

	}
}

void procesarSALIR(int32_t sockPPD)
{
	int32_t comandoEnviado;
	t_NIPC comando;

	NIPC_crearpaquete(NULL, EXIT, 0, NULL, 0, &comando);
	comandoEnviado = NIPC_enviar (sockPPD, comando);
	NIPC_destruirpaquete(&comando);
	printf("Saliendo del PPD... \n");
	exit(0);
}
